package com.alstudio.utils.android.net.http.http2;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;

import android.text.TextUtils;

import com.alstudio.utils.android.ALFileManager;

public class UploadMediaRequest {

	public static final String TAG = UploadMediaRequest.class.getSimpleName();

	public static final int FILE_TYPE_IMAGE = 1; // 图片
	public static final int FILE_TYPE_AUDIO = 2; // 语音
	public static final int FILE_TYPE_VIDEO = 3; // 视频

	public static final int STATUS_OK = 200; // 成功
	public static final int ERROR_UNKNOW = -1; // 未知错误
	public static final int ERROR_NET_EXCEPTION = -2; // 网络异常
	public static final int ERROR_FILE_NOT_EXIST = -3; // 文件不存在
	public static final int ERROR_FILE_INVALID = -4; // 非法文件名或内容

	private HttpUploadRequest httpRequest = null;

	private String userId;
	private int fileType;
	private String filepath;
	private String url;

	public UploadMediaRequest(String servletUrl, String token, String userId,
			int fileType, String filepath) {
		if (TextUtils.isEmpty(servletUrl) || TextUtils.isEmpty(token)
				|| TextUtils.isEmpty(filepath)) {

			throw new IllegalArgumentException();
		}

		this.userId = userId;
		this.fileType = fileType;
		this.filepath = filepath;

		initReqeust(servletUrl, token, userId, fileType, filepath);
	}

	public String getUserId() {
		return userId;
	}

	public int getFileType() {
		return fileType;
	}

	public String getFilepath() {
		return filepath;
	}

	private void initReqeust(String servletUrl, String token, String userId,
			int fileType, String filepath) {
		String fileName = "";
		try {
			fileName = URLEncoder.encode(ALFileManager.getFileName(filepath),
					"UTF-8");
		} catch (UnsupportedEncodingException e) {
			fileName = "";
		}

		String params = "";
		switch (fileType) {
		case FILE_TYPE_IMAGE:
			params = String
					.format("?type=upload&filetype=image&os=android&username=%s&filename=%s",
							userId, fileName);
			break;

		case FILE_TYPE_AUDIO:
			params = String.format(
					"?type=upload&os=android&username=%s&filename=%s", userId,
					fileName);
			break;

		case FILE_TYPE_VIDEO:
			params = String.format(
					"?type=upload&os=android&username=%s&filename=%s", userId,
					fileName);
			break;

		default:
			return;
		}

		url = TextUtils.isEmpty(params) ? servletUrl : servletUrl + params;

		httpRequest = new HttpUploadRequest(url, filepath);
		httpRequest.addHeader("token", token);
	}

	public void request(final MediaUploadCallback callback) {
		httpRequest.request(new HttpHandler(callback));
	}

	public void requestAsync(MediaUploadCallback callback) {
		httpRequest.requestAsync(new HttpHandler(callback));
	}

	public void cancel() {
		httpRequest.cancel();
	}

	private class HttpHandler implements IHttpProgressHandler {
		public MediaUploadCallback callback;

		public HttpHandler(MediaUploadCallback callback) {
			this.callback = callback;
		}

		@Override
		public void handleResponse(HttpResponse response) throws IOException {
			int status = response.getStatusLine().getStatusCode();
			if (status == HttpStatus.SC_OK) {
				Header header = response.getFirstHeader("url");
				String fileId;
				if (header != null) {
					// fileId = ALFileManager.getBareFileId(header.getValue());
					fileId = header.getValue();
				} else {
					fileId = "";
				}

				if (callback != null) {
					if (TextUtils.isEmpty(fileId)) {
						callback.onFailed(UploadMediaRequest.this, ERROR_UNKNOW);
					} else {
						callback.onSuccess(UploadMediaRequest.this, fileId);
					}
				}

			} else {

				if (callback != null)
					callback.onFailed(UploadMediaRequest.this,
							ERROR_NET_EXCEPTION);

			}

		}

		@Override
		public void handleProgress(long transferred, long fileSize) {
			if (callback != null)
				callback.onProcessing(UploadMediaRequest.this, transferred,
						fileSize);
		}

		@Override
		public void handleInterrupted() {
			if (callback != null)
				callback.onCancelled(UploadMediaRequest.this);
		}

		@Override
		public void handleException(Exception e) {
			if (callback != null) {
				if (e instanceof FileNotFoundException) {
					callback.onFailed(UploadMediaRequest.this,
							ERROR_FILE_NOT_EXIST);

				} else {
					callback.onFailed(UploadMediaRequest.this,
							ERROR_NET_EXCEPTION);

				}
			}

		}
	}

	public static interface MediaUploadCallback {
		public void onSuccess(UploadMediaRequest sender, String fileId);

		public void onFailed(UploadMediaRequest sender, int errCode);

		public void onCancelled(UploadMediaRequest sender);

		public void onProcessing(UploadMediaRequest sender, long processedSize,
				long totalSize);
	}
}
